/**
 * 单例模式常见写法,最推荐枚举方法、即SingletonExample7
 *
 * 单例关键点
 * 1、私有构造器
 * 2、静态instance属性(因为面向对象思想的存在,一般把属性定义为private)
 * 3、提供getter方法
 *
 * 懒汉与饿汉实现区别
 * 饿汉:直接定义时初始化为instance = new SingletonExample2(),固定写法、背也要背会!
 * 懒汉:定义时初始化为instance=null,然后在getInstance()方法中获取单实例
 *     这种延迟获取实例的方法,又引出了线程安全/线程不安全问题,通过使用synchronized、volatile等关键字解决
 *
 * | 名称                         | 样例              | 是否线程安全 | 备注                                                         |
 * | ---------------------------- | ----------------- | ------------ | ------------------------------------------------------------ |
 * | 懒汉模式                     | SingletonExample1 | 否           | 最普通写法，但线程不安全                                     |
 * | 饿汉模式                     | SingletonExample2 | 是           | 线程安全，饿汉模式的两种写法均线程安全                       |
 * | 懒汉模式之synchronized       | SingletonExample3 | 是           | 线程安全，但<u>不推荐</u>该写法<br />由Concurrency05"并发最佳实践可知"：宁可使用同步代码块，也不实用同步的方法。主要还是性能原因。 |
 * | 懒汉模式之双重检测           | SingletonExample4 | 否           | 先判断instance=null，然后锁"类名.class"(即类锁而不是对象锁)，再次判断instance=null时、进行初始化new操作。<br />因为指令重排序的存在故仍为线程不安全。 |
 * | 懒汉模式之双重检测加volatile | SingletonExample5 | 是           | 在上面的基础上，添加了volatile关键字禁止指令重排序，故线程安全 |
 * | 饿汉模式之静态代码块         | SingletonExample6 | 是           | 线程安全，饿汉模式的两种写法均线程安全。<br />与SingletonExample2感觉区别不大，static是按序执行的，前者是定义时直接new、后者是立马紧跟了个静态代码块，反正都在getInstance()方法之前已经初始化好了单实例 |
 * | 枚举                         | SingletonExample7 | 是           | 最推荐写法，背也要背会！(注:枚举默认构造方法为private修饰)   |
 */
package cn.dm.example.singleton;